#include "Rbn.h"

#include <cstdlib>
#include <new>
using std::bad_alloc;

#include <cstring>
using std::memcpy;
using std::memset;

#include "../../base.h"

#include "RbnNode.h"

namespace RBN {

/*
	Rbn
*/

/*	public	*/

void* Rbn::operator new(size_t size) {
	/* memory */
	void* memory = malloc(size); 

	/* check validity */
	if (memory == 0) {
		throw bad_alloc();
	}

	return memory;
}

void Rbn::operator delete(void* memory) {
	free(memory);
}

Rbn::Rbn(int nInputs, int nNodes, RbnNode** nodes) :
	_nInputs(nInputs),
	_nNodes(nNodes),
	_nodes(nodes) {

	/* inputs/outputs init */
	_inputs  = new int[nNodes + nInputs];
	_outputs = new int[nNodes];

	/* inputs/outputs zero initialisation */
	memset(_inputs,  0, (nNodes + nInputs) * sizeof(int));
	memset(_outputs, 0, nNodes * sizeof(int));

	/* set nodes inputs/outputs */
	for(int i = 0; i != nNodes; ++i) {
		nodes[i]->setInputsOutputs(i, _inputs, _outputs);
	}
}

Rbn::~Rbn() {
	/* nodes */
	deleteall<RbnNode>(_nodes, _nNodes);
	delete[] _nodes;

	/* inputs/outputs */
	delete[] _inputs;
	delete[] _outputs;
}

void Rbn::update() {
	/* nodes count */
	int nNodes = _nNodes;

	/* update nodes */
	for(int i = 0; i != nNodes; ++i) {
		_nodes[i]->update();
	}

	/* update inputs from nodes */
	memcpy(_inputs, _outputs, nNodes * sizeof(int));
}

int Rbn::getOutputSize() const {
	return _nNodes;
}

int* Rbn::getOutputs() const {
	return _outputs;
}

} // RBN

